// JavaScript Document
function Comments(container) {
	var containerDiv = container;
	// temp data
	var selectedPeople;
	var authors = new Array();
	var comments = new Array();
    var person_view_link = "person_view.php?id=";
	
	/* View state variables */
	this.filter_enum = {
		"unfiltered": 0,
		"all_filtered": 1,
		"byKeywords": 2,
		"byPeople": 3,
        "byPersonInThread": 4
	}
	
	this.sort_enum = {
		"byNameDesc": 0,
		"byNameAsc": 1,
		"byRateDesc": 2,
		"byRateAsc": 3,
		"byDateDesc": 4,
		"byDateAsc": 5
	}
	
	this.view_state = {
		"filteredBy": this.filter_enum.unfiltered,
		"sortedBy": this.sort_enum.byNameAsc
	}

	// private:
	/* Data model manipulations */
	function sortNodesByRateDesc(x,y) {
		return y.RATEBYANNO-x.RATEBYANNO;
	}
	
	function sortNodesByRateAsc(x,y) {
		return x.RATEBYANNO-y.RATEBYANNO;
	}
	
	function sortNodesByNameDesc(x,y) {
		var x_name = author_name_byId(x.PERSONID);
		var y_name = author_name_byId(y.PERSONID);
		return y_name.charAt(0)> x_name.charAt(0);
	}
	
	function sortNodesByNameAsc(x,y) {
		var x_name = author_name_byId(x.PERSONID);
		var y_name = author_name_byId(y.PERSONID);
		return x_name.charAt(0)> y_name.charAt(0);
	}
	
	function sortNodesByDateDesc(x,y) {
		var x_date_text = x.DATECREATED;
		var x_tokens = x_date_text.split("-");
		var x_date = new Date(x_tokens[0],x_tokens[1]-1,x_tokens[2]);

		var y_date_text = y.DATECREATED;
		var y_tokens = y_date_text.split("-");
		var y_date = new Date(y_tokens[0],y_tokens[1]-1,y_tokens[2]);

		return x_date < y_date;
	}

	function sortNodesByDateAsc(x,y) {
		var x_date_text = x.DATECREATED;
		var x_tokens = x_date_text.split("-");
		var x_date = new Date(x_tokens[0],x_tokens[1]-1,x_tokens[2]);

		var y_date_text = y.DATECREATED;
		var y_tokens = y_date_text.split("-");
		var y_date = new Date(y_tokens[0],y_tokens[1]-1,y_tokens[2]);

		return x_date > y_date;
	}
	
	// public:
	this.display_comments = function() {
		containerDiv.innerHTML = "";
		switch(this.view_state.sortedBy)
		{
				case this.sort_enum.byNameDesc:
						comments.sort(sortNodesByNameDesc);
						break;
				case this.sort_enum.byNameAsc:
						comments.sort(sortNodesByNameAsc);
						break;
				case this.sort_enum.byRateDesc:
						comments.sort(sortNodesByRateDesc);
						break;
				case this.sort_enum.byRateAsc:
						comments.sort(sortNodesByRateAsc);
						break;
				 case this.sort_enum.byDateDesc:
						comments.sort(sortNodesByDateDesc);
						break;
				case this.sort_enum.byDateAsc:
						comments.sort(sortNodesByDateAsc);
						break;
				default:
		}
		
		switch(this.view_state.filteredBy)
		{
				case this.filter_enum.unfiltered:
						generate_comments(unfiltered, null);
						break;
				case this.filter_enum.all_filtered:
						generate_comments(all_filtered, null);
						break;
				case this.filter_enum.byKeywords:
						generate_comments(filter_keywords,getKeywords()) ;
						break;
				case this.filter_enum.byPeople:
                                                generate_comments(filter_people,selectedPeople) ;
						break;
                                case this.filter_enum.byPersonInThread:
						generate_comments(filter_people,selectedPeople) ;
						break;
				default:                 
		}
               $(document).ready(function(){

                    $("div.quotetitle").click(function () {
                        $("div.quotebody").filter(":visible").slideUp("slow");
                        var nextDiv = $(this).next();
                        if(nextDiv.is(":visible"))
                           nextDiv.slideUp("slow");
                        else
                           nextDiv.slideDown("slow");
                    });
                })
	}
	
	this.update_comments = function(data) {
		comments=data.comments;
		authors=data.authors;
		commentsWidget.display_comments();
	}
	
	function generate_comments(filter, params) {
			for(var i=0; i < comments.length; i++){
					var curRootNode = comments[i];
                        var groupComments = document.createElement('div');
                        if(commentsWidget.view_state.filteredBy ==commentsWidget.filter_enum.byPersonInThread  && params.length ==1){
                            if(get_node(curRootNode, params[0], "PERSONID")!=null)
                                generate_rootnode_view(curRootNode,unfiltered,params,groupComments);
                            else
                                generate_rootnode_view(curRootNode,all_filtered,params,groupComments);

                        }
                        else{
                            generate_rootnode_view(curRootNode,filter,params,groupComments);
                        }
                groupComments.className = "groupComments";
                containerDiv.appendChild(groupComments);

			}
	}

	/* Filters */
	function unfiltered(node, params){
			return true;
	}
	
	function all_filtered(node, params){
			return false;
	}
	
	function filter_people(node, params){
		 var people = params;
                 if(people.length ==0)
                     return true;
		 for(var i = 0; i<people.length; i++){
				 if(node.PERSONID==people[i])
						 return true;
		 }
		 return false;
	}
	
	function filter_keywords(node, params){
		 var keywords = params;
		 var annot = node.ANNOTATIONBODY;
		 for(var i = 0; i<keywords.length; i++){
				 if(annot.search(keywords[i])!=-1)
						 return true;
		 }
		 return false;
	}
	/* View generation */
	function generate_rootnode_view(root, filter, params, groupComments) {
		//if (typeof(root) == "undefined") return;
		if(root.CHILDREN!=null)
            root.firstChild = root.CHILDREN[0];
		root.visited = false;
		root.parentNode = null;
		root.isInit = false;
		root.level = 0;
		var node = root;

		while(node){
			if(!node.isInit)
				initializeChildren(node);

			if(node.visited) {
				 node.visited = false;
				 if(node==root)
					 break;
				 if(node.nextSibling)
					 node = node.nextSibling;
				 else
					 node = node.parentNode;
			}
			else{
				if(filter(node,params))
					outputComment(node, groupComments);
				else
					outputFilteredComment(node, groupComments);
				if(node.firstChild){
					node.visited = true;
					node = node.firstChild;
				}
				else if(node.nextSibling)
					node = node.nextSibling;
				else
					node = node.parentNode;
			}		
		}
	}

            function get_node(root, id, param) {
			if(root.CHILDREN!=null)
                            root.firstChild = root.CHILDREN[0];
			root.visited = false;
			root.parentNode = null;

			var node = root;

			while(node){
                switch(param){
                    case "ID":
                    	if(node.ID ==id)
                    	  	return node;
                    case "PERSONID":
                    	if(node.PERSONID ==id)
                      		return node;
                }

                if(node.visited) {
                	node.visited = false;
                	if(node==root)
                    	break;
                    if(node.nextSibling)
                    	node = node.nextSibling;
                    else
                    	node = node.parentNode;
                }
                else{
                	if(node.firstChild){
                    	node.visited = true;
                    	node = node.firstChild;
                   	}
                 	else if(node.nextSibling)
                      	node = node.nextSibling;
                  	else
                      	node = node.parentNode;
                }
			}
			return null;
	}

        function outputQuote(node, groupComments){

            var quote = document.createElement('div');
            quote.className = "quote";

            var quotetitle = document.createElement('div');
            quotetitle.innerHTML = "<span>Quote</span>";
            quotetitle.className = "quotetitle";

            var quotebody = document.createElement('div');
            if(node.SNAPSHOT!= null)
                quotebody.innerHTML = "<p>" + node.SNAPSHOT + "</p>";
            else
                quotebody.innerHTML = "<p>'No text was selected'</p>"
            quotebody.className = "quotebody";


            quote.appendChild(quotetitle);
            quote.appendChild(quotebody);
            groupComments.appendChild(quote);
        }

        function createComment(node){

                var commentContent = document.createElement('div');
                commentContent.id = "comment_"+node.ID;

                var commentHeadline = document.createElement('div');
                var link = document.createElement('a');
                var full_link = person_view_link + node.PERSONID;
                link.href = full_link;
                link.setAttribute('href', full_link);
                link.innerHTML = author_name_byId(node.PERSONID);
                commentHeadline.className = 'headline';
                commentHeadline.appendChild(link);

                var commentText = document.createElement('div');
                commentText.innerHTML = node.ANNOTATIONBODY;
                commentText.className = 'comment_text';

                var commentVars = document.createElement('div');
                commentVars.className = "comment_vars";

                var spanDate = document.createElement('span');
                spanDate.innerHTML = node.DATECREATED;
                spanDate.className = "date";

                var spanRating = document.createElement('span');
                spanRating.innerHTML = "Rating: "+rateByAnno(node.RATEBYANNO);
                spanRating.className = "rating";

                commentVars.appendChild(spanDate);
                commentVars.appendChild(spanRating);

                commentContent.appendChild(commentHeadline);
                commentContent.appendChild(commentText);
                commentContent.appendChild(commentVars);

                commentContent.className = "comment_content";
                commentContent.style.marginLeft = node.level*20+"px";

                return commentContent;
        }

	function outputComment(node, groupComments){

                        if(node.parentNode==null){
                           outputQuote(node, groupComments);
                           addBeak(groupComments);
                        }

                        var commentContent = createComment(node);

			groupComments.appendChild(commentContent);
	}


	function outputFilteredComment(node, groupComments){

                        if(node.parentNode==null){
                           outputQuote(node, groupComments);
                           addBeak(groupComments);
                        }

			var commentContent = document.createElement('div');
                        commentContent.id = "comment_"+node.ID;
			commentContent.className = "filtered_comment comment_content";

	
			var commentHeadline = document.createElement('div');
                        var link = document.createElement('a');
                        var full_link = person_view_link + node.PERSONID;
                        link.href = full_link;
                        link.setAttribute('href', full_link);
                        link.innerHTML = author_name_byId(node.PERSONID);
                        commentHeadline.appendChild(link);
			commentHeadline.className = 'headline';
	
	
			var spanDate = document.createElement('span');
			spanDate.innerHTML = node.DATECREATED;
			spanDate.className = "date";
			commentHeadline.appendChild(spanDate);

			if (node.RATEBYANNO) {
				var spanRating = document.createElement('span');
				spanRating.innerHTML = "Rating: " + rateByAnno(node.RATEBYANNO);
				spanRating.className = "rating";
				commentHeadline.appendChild(spanRating);
			}
	
			commentContent.appendChild(commentHeadline);
	
			commentContent.style.marginLeft = node.level*30+"px";
			groupComments.appendChild(commentContent);
	}

        function addBeak(groupComments){
            var beak = document.createElement('div');
            beak.className = "beak";
            groupComments.appendChild(beak);
        }

        function rateByAnno(value){
 
          switch(value){
              case 1:
                  //return "negative";
                  return "<IMG src='image/Pos.gif' title='Positive'/>";
              case 2:
                  return "<IMG src='image/Neg.gif' title='Negative'/>";
              case 3:
                  return "<IMG src='image/Neut.gif' title='Neutral'/>";
              case 4:
                  return "<IMG src='image/Info.gif' title='Informative'/>";
	      case 5:
                  return "<IMG src='image/Neut.gif' title='Neutral'/>";
          }
					return "none";
        }


	function initializeChildren(node){
			if(node.CHILDREN.length>0){
					node.firstChild = node.CHILDREN[0];
					for(var i =0; i<node.CHILDREN.length-1; i++){
							node.CHILDREN[i].parentNode = node;
							node.CHILDREN[i].nextSibling = node.CHILDREN[i+1];
							node.CHILDREN[i].level = node.level+1;
					}
					node.CHILDREN[node.CHILDREN.length-1].nextSibling=null;
					node.CHILDREN[node.CHILDREN.length-1].parentNode=node;
					node.CHILDREN[node.CHILDREN.length-1].level=node.level+1;
                                        node.CHILDREN[node.CHILDREN.length-1].visited=false;
			}
			else{
					node.firstChild = null;
			}
			node.isInit = true;
	}

	// public:
	/* Controls */
	this.changeFilter = function(filter_state){
			this.view_state.filteredBy = filter_state;
			this.display_comments();
	}
	
	this.changeSort = function(sort_state){
			this.view_state.sortedBy = sort_state;
			this.display_comments();
	}
	

    	this.getSelectedPeople = function(){
			var selectPeople = new Array();
			// TODO: update DOM object id
			var selectList = document.getElementById("people");
			for(var i=0; i<selectList.options.length; i++){
					if(selectList.options[i].selected==true)
							selectPeople.push(selectList.options[i].value);
			}
			return selectPeople;
	}

        //callback for integration with the network graph
        this.filterThreadsByPeople = function(people){
            selectedPeople = people;
            //this.changeFilter(this.filter_enum.byPeople);
            commentsWidget.changeFilter(commentsWidget.filter_enum.byPersonInThread);
        }

        //callback for integration with the timechart
        this.highlightComment = function(id){

            var comment_id = "comment_"+id;
            var selected = document.getElementById(comment_id);

            var node;
            for(var i=0; i<comments.length; i++){
                node = get_node(comments[i], id, "ID");
                if(node!=null)
                    break;
            }
            if(node==null)
                return;
            var comment = createComment(node);
            selected.innerHTML = comment.innerHTML;
            selected.style.backgroundColor = "#FFFFE0";
            selected.scrollIntoView();
        }
	
	
	function getKeywords(){
			// TODO: update DOM object id
			var keywords = document.getElementById("keywords").value;
			return keywords.split(" ");
	}
	
	/* Helper functions */
	function author_name_byId(id){
			for(var i=0; i<authors.length; i++){
					var current_author = authors[i];
					if(current_author.PERSONID == id){
							return current_author.NAME;
					}
			}
			return "Author Unknown";
	}

       function author_Id_byName(name){
			for(var i=0; i<authors.length; i++){
					var current_author = authors[i];
					if(current_author.NAME.toLowerCase() == name.toLowerCase()){
							return current_author.PERSONID;
					}
			}
			return -1;
	}

	
	function hasChildren(node){
			return node.CHILDREN.length >0? true:false;
	}
	
	
	/*Comment state */
	function getCurrentNodeId(elem){
		return elem.parentNode.parentNode.getAttribute('id');
	}
	
	
}  // class Comments
